#include "get_hash.h"

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int getHashSHA256(const char *file_name, char *sha256)
{
    unsigned char c[EVP_MAX_MD_SIZE];
    unsigned int md_len;
    int i;
    FILE *file;
    EVP_MD_CTX *mdctx;
    int bytes;
    unsigned char data[1024];

    file = fopen(file_name, "rb");
    if (file == NULL)
    {
        printf("Failed to open %s\n", file_name);
        return -1;
    }

    mdctx = EVP_MD_CTX_new();
    if (mdctx == NULL)
    {
        printf("EVP_MD_CTX_new failed.\n");
        fclose(file);
        return -1;
    }

    if (EVP_DigestInit_ex(mdctx, EVP_sha256(), NULL) != 1)
    {
        printf("EVP_DigestInit_ex failed.\n");
        EVP_MD_CTX_free(mdctx);
        fclose(file);
        return -1;
    }

    while ((bytes = fread(data, 1, sizeof(data), file)) > 0)
    {
        if (EVP_DigestUpdate(mdctx, data, bytes) != 1)
        {
            printf("EVP_DigestUpdate failed.\n");
            EVP_MD_CTX_free(mdctx);
            fclose(file);
            return -1;
        }
    }

    if (EVP_DigestFinal_ex(mdctx, c, &md_len) != 1)
    {
        printf("EVP_DigestFinal_ex failed.\n");
        EVP_MD_CTX_free(mdctx);
        fclose(file);
        return -1;
    }

    EVP_MD_CTX_free(mdctx);
    fclose(file);

    for (i = 0; i < md_len; i++)
    {
        sprintf(&sha256[i * 2], "%02x", c[i]);
    }

    return 0;
}

int getHashMD5(const char *file_name, char *md5)
{
    unsigned char c[EVP_MAX_MD_SIZE];
    unsigned int md_len;
    int i;
    FILE *file;
    EVP_MD_CTX *mdctx;
    int bytes;
    unsigned char data[1024];

    file = fopen(file_name, "rb");
    if (file == NULL)
    {
        printf("Failed to open %s\n", file_name);
        return -1;
    }

    mdctx = EVP_MD_CTX_new();
    if (mdctx == NULL)
    {
        printf("EVP_MD_CTX_new failed.\n");
        fclose(file);
        return -1;
    }

    if (EVP_DigestInit_ex(mdctx, EVP_md5(), NULL) != 1)
    {
        printf("EVP_DigestInit_ex failed.\n");
        EVP_MD_CTX_free(mdctx);
        fclose(file);
        return -1;
    }

    while ((bytes = fread(data, 1, sizeof(data), file)) > 0)
    {
        if (EVP_DigestUpdate(mdctx, data, bytes) != 1)
        {
            printf("EVP_DigestUpdate failed.\n");
            EVP_MD_CTX_free(mdctx);
            fclose(file);
            return -1;
        }
    }

    if (EVP_DigestFinal_ex(mdctx, c, &md_len) != 1)
    {
        printf("EVP_DigestFinal_ex failed.\n");
        EVP_MD_CTX_free(mdctx);
        fclose(file);
        return -1;
    }

    EVP_MD_CTX_free(mdctx);
    fclose(file);

    for (i = 0; i < md_len; i++)
    {
        sprintf(&md5[i * 2], "%02x", c[i]);
    }

    return 0;
}
